package cn.stylefeng.guns.modular.demo.excel.listener;

import cn.stylefeng.guns.core.exception.BusinessException;
import cn.stylefeng.guns.core.exception.BusinessExceptionEnum;
import cn.stylefeng.guns.dao.ISaleStockService;
import cn.stylefeng.guns.dao.ISupplierService;
import cn.stylefeng.guns.dao.entity.SaleStock;
import cn.stylefeng.guns.dao.entity.Supplier;
import cn.stylefeng.guns.modular.demo.excel.domain.PurchaseExcelData;
import cn.stylefeng.guns.modular.demo.excel.domain.StockExcelVO;
import com.alibaba.excel.ExcelWriter;
import com.alibaba.excel.context.AnalysisContext;
import com.alibaba.excel.exception.ExcelDataConvertException;
import com.alibaba.excel.read.listener.ReadListener;
import com.alibaba.excel.util.ListUtils;
import com.alibaba.excel.write.metadata.WriteSheet;
import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.compress.utils.Lists;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.*;
import java.util.stream.Collectors;

@Slf4j
public class PurchasePlanListener implements ReadListener<PurchaseExcelData> {

    private List<PurchaseExcelData> dataList;


    /**
     * 如果使用了spring,请使用这个构造方法。每次创建Listener的时候需要把spring管理的类传进来
     *
     * @param
     */
    public PurchasePlanListener(List<PurchaseExcelData> dataList) {
        this.dataList = dataList;
    }


    static final BigDecimal percent60 = new BigDecimal("0.6");
    static final BigDecimal percent30 = new BigDecimal("0.3");
    static final BigDecimal percent10 = new BigDecimal("0.1");
    static final BigDecimal percent1point5 = new BigDecimal("1.5");

    /**
     * p  平均月销 =M18*60%+(N18-M18)*30%+(O18-N18)*10%
     * Q  平均月销计划 =IF(P18>1.5*(V18+Y18),P18-(V18+Y18),0)
     * R 平均配送 =K18*1
     * S  平均配送计划 =IF(AND(R18>2*(W18+Y18),R18>2*P18),0,R18-(W18+Y18))
     * T  最终计划 =IF(Q18>S18,Q18,S18)
     *
     * @param data    one row value. It is same as {@link AnalysisContext#readRowHolder()}
     * @param context
     */
    @Override
    public void invoke(PurchaseExcelData data, AnalysisContext context) {
        try {
            BigDecimal M = defaultValue(data.getThirtyDaysStoreSales());
            BigDecimal N = defaultValue(data.getSixtyDaysStoreSales());
            BigDecimal O = defaultValue(data.getNinetyDaysStoreSales());
            //(N18-M18)*30%
            BigDecimal subtract = N.subtract(M);
            BigDecimal multiply = subtract.multiply(percent30);

            //M18*60%
            BigDecimal multiply2 = M.multiply(percent60);

            //(O18-N18)*10%
            BigDecimal subtract3 = O.subtract(N);
            BigDecimal multiply3 = subtract3.multiply(percent10);
            //P
            BigDecimal P = multiply.add(multiply2).add(multiply3);
            data.setAverageMonthlySales(P);
            //Q = IF(P18>1.5*(V18+Y18),P18-(V18+Y18),0)
            BigDecimal V = Objects.isNull(data.getWarehouseAvailableStock()) ? new BigDecimal(0) : data.getWarehouseAvailableStock();
            BigDecimal Y = Objects.isNull(data.getDeliveryInTransit()) ? new BigDecimal(0) : data.getDeliveryInTransit();
            BigDecimal add = V.add(Y);
            BigDecimal multiply1 = add.multiply(percent1point5);
            BigDecimal Q = null;
            if (P.compareTo(multiply1) == 1) {
                Q = P.subtract(add);
            } else {
                Q = new BigDecimal(0);
            }
            data.setAverageMonthlySalesPlan(Q);
            //S 平均配送计划 =IF(AND(R18>2*(W18+Y18),R18>2*P18),0,R18-(W18+Y18))
            int k = defaultValue(data.getThirtyDaysDelivery()).intValue();
            int r = k;
            int w = defaultValue(data.getStoreStock()).intValue();
            int y = defaultValue(data.getDeliveryInTransit()).intValue();
            BigDecimal multiply4 = P.multiply(new BigDecimal(2));
            BigDecimal R = new BigDecimal(r);
            BigDecimal S;
            if (r > 2 * (w + y) && R.compareTo(multiply4) == 1) {
                S = new BigDecimal(0);
            } else {
                //R18-(W18+Y18))
                S = R.subtract(new BigDecimal(w + y));
            }
            data.setAverageDeliveryPlan(S);
            //T  最终计划 =IF(Q18>S18,Q18,S18)
            BigDecimal T;
            if (Q.compareTo(S) == 1) {
                T = Q;
            } else {
                T = S;
            }

            data.setFinalPlan(T);
            data.setFinalPlan2(peruse(T, data.getLargePackage(), defaultValue(data.getLastPurchasePrice())));
        } catch (Exception e) {
            throw e;
        } finally {
            this.dataList.add(data);
        }
    }

    private BigDecimal defaultValue(BigDecimal data) {
        return Objects.isNull(data) ? new BigDecimal(0) : data;
    }

    private BigDecimal peruse(BigDecimal data, Integer largePackage, BigDecimal lastPurchasePrice) {
        //小于10盒
        if (data.compareTo(new BigDecimal(10)) == -1) {
            return data.setScale(0, RoundingMode.HALF_UP);
        } else if (data.compareTo(new BigDecimal(100)) == -1) {
            //大于50块钱的
            if (lastPurchasePrice.compareTo(new BigDecimal(50)) == 1) {
                //大于15盒的
                if (data.compareTo(new BigDecimal(15)) == 1) {
                    return new BigDecimal(15);
                } else {
                    return new BigDecimal(10);
                }
            } else {
                return data.setScale(0, RoundingMode.HALF_UP);
            }
        } else {
            int num = data.intValue();
            return new BigDecimal((num / largePackage + 1) * largePackage);
        }

    }


    @Override
    public void onException(Exception exception, AnalysisContext context) {
        log.error("解析失败，但是继续解析下一行:{}", exception.getMessage());
        exception.printStackTrace();
        // 如果是某一个单元格的转换异常 能获取到具体行号
        // 如果要获取头的信息 配合invokeHeadMap使用
        if (exception instanceof ExcelDataConvertException) {
            ExcelDataConvertException excelDataConvertException = (ExcelDataConvertException) exception;
            log.error("第{}行，第{}列解析异常，数据为:{}", excelDataConvertException.getRowIndex(), excelDataConvertException.getColumnIndex(), excelDataConvertException.getCellData());
//            errorList.add("第" + excelDataConvertException.getRowIndex() + "行，第" + excelDataConvertException.getColumnIndex() + "列解析异常，数据为:" + excelDataConvertException.getCellData());
        } else if (exception instanceof BusinessException) {
            log.error("业务异常", exception);
//            errorList.add(exception.getMessage());
        } else if (exception instanceof IllegalArgumentException) {
            log.error("业务异常", exception);
        }

    }

    /**
     * 所有数据解析完成了 都会来调用
     *
     * @param context
     */
    @Override
    public void doAfterAllAnalysed(AnalysisContext context) {
        // 这里也要保存数据，确保最后遗留的数据也存储到数据库
        log.info("所有数据解析完成！");
    }


}
